package com.liqiye.paymanager.service.evaluate;

import com.liqiye.paymanager.bean.common.IpLocation;
import com.liqiye.paymanager.entity.Order;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.AsnResponse;
import com.maxmind.geoip2.model.CityResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.util.List;

/**
 *
 */
@Service
@Slf4j
public class IpLocationService {

    private final DatabaseReader cityReader;
    private final DatabaseReader asnReader;

    /**
     * 这个 GeoLite2 的数据库需要经常更新（保证准确性），官方推荐的更新方法有两个：
     * 1、手动去官网下载这个数据库文件更新
     * 2、使用官方的 GeoIP 更新程序
     * https://www.maxmind.com/en/accounts/1201337/geoip/downloads
     */
    public IpLocationService() throws IOException {
        File cityDatabase = new ClassPathResource("maxmind/GeoLite2-City.mmdb").getFile();
        cityReader = new DatabaseReader.Builder(cityDatabase).build();
        File asnDatabase = new ClassPathResource("maxmind/GeoLite2-ASN.mmdb").getFile();
        asnReader = new DatabaseReader.Builder(asnDatabase).build();
    }


    public IpLocation lookup(String ip) {
        try {
            InetAddress ipAddress = InetAddress.getByName(ip);

            CityResponse cityResponse = cityReader.city(ipAddress);
            String country = cityResponse.getCountry().getIsoCode(); // 如 US
            String city = cityResponse.getCity().getName();          // 如 Los Angeles
            // String isp = cityResponse.getTraits().getAutonomousSystemOrganization(); // ISP

            AsnResponse asnResponse = asnReader.asn(ipAddress);
            String isp = asnResponse.getAutonomousSystemOrganization();

            return new IpLocation(ip, country, city, isp);
        } catch (Exception e) {
            e.printStackTrace();
            return new IpLocation(ip, "UNKNOWN", "UNKNOWN", "UNKNOWN");
        }
    }

    public void filter(String ip) {
        IpLocation ipLocation = this.lookup(ip);
        String isp = ipLocation.getIsp();
        String country = ipLocation.getCountry();

        // 风险分数（0代表健康）
        Integer riskScore = 0;


        List<String> forbidden = List.of("IR", "KP", "CU");
        if (forbidden.contains(country)) {
            riskScore += 30;
            log.warn("来自禁止国家的交易");
        }


        Order order = new Order();
        order.setBillingCountry("US");
        if (!country.equalsIgnoreCase(order.getBillingCountry())) {
            riskScore += 30;
            log.warn("下单国家与 IP 国家不一致");
        }



        if (isp == null || isp.equalsIgnoreCase("UNKNOWN")) {
            riskScore += 5;
            log.warn("无法识别 ISP，存在风险");
        }
        if (isp.contains("Amazon") || isp.contains("DigitalOcean") || isp.contains("OVH")) {
            riskScore += 40;
            log.warn("ISP是数据中心，可能是代理");
        }


        // 如果要判断一个 IP 是否为 VPN/代理，GeoLite 免费版本不支持，需要用MaxMind 的 GeoIP2 Anonymous IP 数据库（商业版）
        // 或者用 IP 识别服务的 第三方 REST API（入门级：IPHub、高端：IPQualityScore）
        // https://iphub.info/
        // https://www.ipqualityscore.com/


        log.warn("风险分数：" + riskScore);

    }


}
